#include "CanAscLogger.h"
#include <QDebug>

CanAscLogger::CanAscLogger(QObject *parent) : QObject(parent),
    m_ascFile(nullptr),
    m_ascStream(nullptr),
    m_channel(1)
{

}

CanAscLogger::~CanAscLogger()
{
    closeLogFile();
}

bool CanAscLogger::initLogFile(const QString &baseFileName, const QString &mode)
{
    qInfo() << "日志记录文件格式：" << mode;
    // 先关闭已有的文件
    closeLogFile();

    // 保存当前模式
    m_mode = mode;

    // 创建新文件
    QString fileName = generateFileName(baseFileName, mode);
    m_ascFile = new QFile(fileName);

    if (!m_ascFile->open(QIODevice::WriteOnly | QIODevice::Text)) {
        qInfo() << "无法打开ASC日志文件:" << m_ascFile->errorString();
        delete m_ascFile;
        m_ascFile = nullptr;
        return false;
    }

    m_ascStream = new QTextStream(m_ascFile);
    m_ascStream->setCodec("UTF-8");
    if( m_mode == "ASC" ){
        // 写入ASC文件头部信息
        *m_ascStream << "date " << QDate::currentDate().toString("yyyy.MM.dd") << endl;
        *m_ascStream << "time " << QTime::currentTime().toString("hh:mm:ss.zzz") << endl;
        *m_ascStream << "base hex  timestamps absolute" << endl;
        *m_ascStream << "no internal events logged" << endl;
        *m_ascStream << endl;
    }

    if( m_mode == "CSV" ){
        // 写入CSV文件头部
        *m_ascStream << "时间戳 帧率" << endl;
    }

    return true;
}

void CanAscLogger::closeLogFile()
{
    QMutexLocker locker(&m_fileMutex);

    if (m_ascStream) {
        m_ascStream->flush();
        delete m_ascStream;
        m_ascStream = nullptr;
    }

    if (m_ascFile) {
        if (m_ascFile->isOpen()) {
            m_ascFile->close();
        }
        delete m_ascFile;
        m_ascFile = nullptr;
    }
}

//接收数据日志方法
void CanAscLogger::logReceivedData(quint32 msgId, const QByteArray &data,
                                 const QString &msgName, const QString &sigName,
                                 double physValue, const QString &valueDesc)
{
    if (!m_ascFile || !m_ascStream || !m_ascFile->isOpen())
        return;

    QMutexLocker locker(&m_fileMutex);
    QString timeStr = getFormattedTime();

    // 确保数据长度不超过8字节（标准CAN帧）
    int dataLength = qMin(data.size(), 8);

    // 构建完整的8字节数据（不足补0）
    QByteArray paddedData = data.left(dataLength);
    while (paddedData.size() < 8) {
        paddedData.append((char)0x00);
    }

    // 修复格式：确保每个数据字节单独显示，用空格分隔
    QString dataStr;
    for (int i = 0; i < dataLength; ++i) {
        dataStr += QString("%1 ").arg((quint8)paddedData[i], 2, 16, QLatin1Char('0')).toUpper();
    }
    // 移除末尾多余的空格
    dataStr = dataStr.trimmed();

    // 构建ASC格式的接收记录（修正版）
    QString logLine = QString("%1 %2  Rx   d %3 %4 %5")
        .arg(timeStr, -12)          // 时间戳左对齐，固定宽度
        .arg(m_channel)             // 通道号
        .arg(msgId, 8, 16, QLatin1Char('0')) // 8位十六进制ID，大写
        .arg(dataLength)            // 数据长度（1-8）
        .arg(dataStr);              // 空格分隔的字节数据

    *m_ascStream << logLine << endl;

    // 记录解析后的信号信息
    if (!msgName.isEmpty() && !sigName.isEmpty()) {
        QString sigLine = QString(";  %1: %2 = %3 %4")
            .arg(msgName)
            .arg(sigName)
            .arg(physValue)
            .arg(valueDesc);
        *m_ascStream << sigLine << endl;
    }
}

//发送数据日志方法
void CanAscLogger::logSentData(quint32 msgId, const QByteArray &data, const QString &msgName)
{
    if (!m_ascFile || !m_ascStream || !m_ascFile->isOpen())
        return;

    QMutexLocker locker(&m_fileMutex);
    QString timeStr = getFormattedTime();

    // 确保数据长度不超过8字节
    int dataLength = qMin(data.size(), 8);

    // 构建完整的8字节数据（不足补0）
    QByteArray paddedData = data.left(dataLength);
    while (paddedData.size() < 8) {
        paddedData.append((char)0x00);
    }

    // 修复格式：每个数据字节单独显示，用空格分隔
    QString dataStr;
    for (int i = 0; i < dataLength; ++i) {
        dataStr += QString("%1 ").arg((quint8)paddedData[i], 2, 16, QLatin1Char('0')).toUpper();
    }
    dataStr = dataStr.trimmed();

    // 构建ASC格式的发送记录（修正版）
    QString logLine = QString("%1 %2  Tx   d %3 %4 %5")
        .arg(timeStr, -12)          // 时间戳左对齐
        .arg(m_channel)             // 通道号
        .arg(msgId, 8, 16, QLatin1Char('0')) // 8位十六进制ID
        .arg(dataLength)            // 数据长度
        .arg(dataStr);              // 空格分隔的字节数据

    *m_ascStream << logLine << endl;

    // 记录消息名称
    if (!msgName.isEmpty()) {
        *m_ascStream << ";  Send Message: " << msgName << endl;
    }
}

QString CanAscLogger::generateFileName(const QString &baseName, const QString &mode)
{
    QDateTime now = QDateTime::currentDateTime();
    QString fileName;
    if( mode == "ASC" )
        fileName = QString("%1_%2.asc")
                .arg(baseName)
                .arg(now.toString("yyyyMMdd_hhmmss"));
    if( mode == "CSV" )
        fileName = QString("%1_%2.csv")
                .arg(baseName)
                .arg(now.toString("yyyyMMdd_hhmmss"));

    return fileName;
}

QString CanAscLogger::getFormattedTime()
{
    return QTime::currentTime().toString("hh:mm:ss.zzz");
}

// 新增：格式化数据用于CSV
QString CanAscLogger::formatDataForCsv(const QByteArray &data)
{
    // 转换为十六进制字符串
    QString hexStr;
    for (int i = 0; i < data.size(); ++i) {
        hexStr += QString("%1 ").arg((quint8)data[i], 2, 16, QLatin1Char('0')).toUpper();
    }
    hexStr = hexStr.trimmed();

    QString strData = QString::fromUtf8(data);
    bool isPrintable = true;

    for (int i = 0; i < strData.size(); ++i) {
        ushort c = strData[i].unicode();
        // 检查是否为可打印字符（ASCII 32-126 或制表符、换行等控制字符）
        if (!((c >= 0x20 && c <= 0x7E) || c == '\t' || c == '\n' || c == '\r')) {
            isPrintable = false;
            break;
        }
    }

    if (isPrintable && !strData.isEmpty()) {
        return QString("%1 (文本: %2)").arg(hexStr).arg(strData);
    }

    return hexStr;
}

//记录datagram数据的方法
void CanAscLogger::logCameraDatagram(const QByteArray &datagram, const QHostAddress &sender,
                             quint16 senderPort, bool isFromServer)
{
    if (!m_ascFile || !m_ascStream || !m_ascFile->isOpen() || m_mode != "CSV")
        return;

    QMutexLocker locker(&m_fileMutex);
    QString timeStr = getFormattedTime();
    int dataLength = datagram.size();
    QString dataStr = formatDataForCsv(datagram);
    QString nodeType = isFromServer ? "服务端" : "未知节点";

    // CSV格式的datagram记录
    QString logLine = QString("%1,UDP数据,,,%2,%3,%4,%5,%6")
        .arg(timeStr)
        .arg(dataLength)
        .arg(dataStr)
        .arg(sender.toString())
        .arg(senderPort)
        .arg(nodeType);

    *m_ascStream << logLine << endl;
}
